package com.kolakcc.loljclient.controller;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Collection;

import javax.swing.SwingWorker;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Mode;

import com.kolakcc.loljclient.model.Status;
import com.kolakcc.loljclient.model.XMPPWrapper;
import com.kolakcc.loljclient.model.swing.FriendsListModel;
import com.kolakcc.loljclient.model.swing.StatusComboBoxModel;
import com.kolakcc.loljclient.view.FriendsListView;

public class FriendsListController extends KolaController implements
		MouseListener, DocumentListener {
	private FriendsListView view;
	protected FriendsListModel onlineModel;
	protected FriendsListModel offlineModel;
	SwingWorker<Void, Void> connectionWorker;

	public FriendsListController(String username, String password) {
		this.view = new FriendsListView();
		this.setView(this.view);
		this.initializeWorkers(username, password);
		this.view.onlineList.addMouseListener(this);
		this.view.presenceComboBox.setModel(new StatusComboBoxModel());
		this.view.presenceStatusField.getDocument().addDocumentListener(this);
		this.connectionWorker.execute();
	}

	public void initializeWorkers(final String username, final String password) {
		this.connectionWorker = new SwingWorker<Void, Void>() {
			protected Void doInBackground() throws Exception {
				XMPPWrapper.login(username, password);
				XMPPWrapper.getConnection().getRoster()
						.addRosterListener(new RosterListener() {
									public void entriesAdded(Collection<String> addresses) {
									}

									public void entriesDeleted(Collection<String> addresses) {
									}

									public void entriesUpdated(Collection<String> addresses) {
									}

									public void presenceChanged(Presence presence) {
										FriendsListController.this.refreshLists();
									}
								});
				FriendsListController.this.refreshLists();
				XMPPWrapper.getConnection().getChatManager()
						.addChatListener(new ChatManagerListener() {
							public void chatCreated(Chat chat,
									boolean createdLocally) {
								if (!createdLocally) {
									chat.addMessageListener(new FriendChatController(
											chat));
								}
							}
						});
				return null;
			}
		};
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if (e.getClickCount() == 2) {
			// TODO: one window per friend;
			new FriendChatController(
					this.onlineModel.getFriendAt(this.view.onlineList
							.getSelectedIndex()));
		}
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
	}

	@Override
	public void mouseReleased(MouseEvent e) {
	}

	public void refreshLists() { // TODO: rewrite to use an update instead of a replace
		this.onlineModel = new FriendsListModel(
				FriendsListModel.ShowMode.ONLINE);
		this.offlineModel = new FriendsListModel(
				FriendsListModel.ShowMode.OFFLINE);
		this.view.onlineList.setModel(this.onlineModel);
		this.view.offlineList.setModel(this.offlineModel);
	}

	public void updateStatus() {
		String statusXML = String.format("<body><statusMsg>%s</statusMsg></body>", this.view.presenceStatusField.getText());
		Status selectedStatus = (Status) this.view.presenceComboBox.getSelectedItem();
		Mode presenceMode = Presence.Mode.chat;
		if (selectedStatus.getDisplay().equals("Away")) presenceMode = Presence.Mode.away;
		Presence newPresence = new Presence(Presence.Type.available,statusXML,1,presenceMode);
		XMPPWrapper.getConnection().sendPacket(newPresence);
	}
	@Override
	public void insertUpdate(DocumentEvent e) {
		updateStatus();
	}

	@Override
	public void removeUpdate(DocumentEvent e) {
		updateStatus();
	}

	@Override
	public void changedUpdate(DocumentEvent e) {
	}
}
